parser grammar cFormatParser;

options {
  language = Java;
  tokenVocab = cFormatLexer;
}

@header {package PL.practica8;}

@members {
  private String resultado = "", parcial = "";

  public String getResult() {
    return resultado;
  }
  ArrayList <RecognitionException> errores = new ArrayList<RecognitionException>();

public boolean listaVacia (){
    if (errores.isEmpty()){
      return true;
    }else
      return false;
}

public ArrayList getListaErrores(){return errores;}


@Override
public void reportError (RecognitionException e){
  System.err.println (getErrorMessage(e, getTokenNames()));
  errores.add(e);
}
 
  
}


//reglas para hacer mas legible las reglas MAS COMPLEJAS 
tipo returns [String s = ""] : v = VOID {s += v.getText();}
                             | c = CHAR  {s += c.getText();}
                             | f = FLOAT {s += f.getText() ;}
                             | i = INT   {s += i.getText() ;};
parametro returns [String s = ""] : str= CADENA {s += str.getText();}
          | c = CARACTER {s += c.getText();}
          | n = NUMERO  { s += Integer.parseInt(n.getText());};
          
def_parametros returns [String s =""]: t1 =tipo {s+=t1+" ";}  p1 = parametro {s+=p1;} (COMA {s+=", ";} t2 =tipo {s+=t2 +" ";} p2 =parametro {s+= p2;})*  {s+= ' ';};          
  cabecerafuncion returns [String s = ""]: t =tipo {s+=t+" ";} id=ID {s+=id.getText() + ' ';} ABRIRPARENTESIS {s+='(';} (dp = def_parametros? {s+= dp;} | v =VOID {s+="void";}) CERRARPARENTESIS {s+= ")";};

//parametros returns [String s = ""] : p1 = parametro {s += p1.getText() + ' ';}  (COMA {s+= ',';}  p2= parametro {s += p2.getText() + ' ';})*;


        
op_log returns [String s = ""] : OP_OR {s+= "||";}
       | OP_AND {s+= "&&";};


entrada : (parcial = sentencia {resultado += parcial;} | parcial = metodo {resultado += parcial;})*   /*{System.out.println (resultado);}*/;

 asignacion returns [String s = ""] :  id = ID {s += id.getText();} ASIGNACION {s+= " = ";} e=expr {s += e;};
                                  
 declaracion returns [String s = ""]: t =tipo {s += t + " ";} id =ID {s += id.getText();}  (COMA  {s+= ", ";} id=ID {s += id.getText() ;})* ;

printf returns [String s = ""] :  PRINTF{s+= "printf"+ ' ';} ABRIRPARENTESIS {s+='(';}  str =CADENA {s+=str.getText();} (COMA {s+=", ";} id=ID {s+=id.getText();})* CERRARPARENTESIS {s+=')';} ;

metodo returns [String s = ""] : cf= cabecerafuncion {s+=cf;} b =bloqueLlaves {s+=b;};

sentencia returns [String s = ""] : 
            ((a= asignacion {s += a;} | p = printf {s+=p;}| d=declaracion {s+=d;}) SEPARADOR  {s+= ";\r\n";}) 
            |ci = condicionif {s += ci;};

bloqueLlaves returns [String s = ""] : ABRIRLLAVE {s+= "{\r\n" ;} 
                                       (sent = sentencia {s += sent;})*
                                       CERRARLLAVE {s+= "}\r\n" ;};



condicionif returns [String s = ""] : IF {s+= "if"+ " ";}  ABRIRPARENTESIS {s+= "(" ;}  cd = cond {s += cd;} CERRARPARENTESIS {s+= ")" ;}
 (sent = sentencia {s += sent;}| b = bloqueLlaves {s += b;} );
    cond returns [String s = ""] : (OP_NOT)? cond_expr ( ol = op_log {s+= ol +' ';} (OP_NOT)?  ce = cond_expr {s+= ce + ' ';})*;
    cond_expr returns [String s = ""] : ex = expr {s += ex + ' ';} (OP_COMP expr)*;

 expr returns [String s = ""]: em1 = exp_mult {s+=em1;} ((MAS {s+= " + ";} em2=exp_mult {s+=em2;} ) | (MENOS {s+= " - ";} em3=exp_mult {s+=em3+" ";}))*;   
 exp_mult returns [String s = ""]  : ex1=exp_base {s+=ex1;} ((ASTERISCO {s+= " * ";} ex2=exp_base {s+=ex2;}) | (SLASH {s+= "/";} ex3=exp_base {s+=ex3;}))* ;
 exp_base returns [String s = ""] :  n = NUMERO  { s += Integer.parseInt(n.getText());}
             | ABRIRPARENTESIS {s+= "(";} e=expr {s+= e;}  CERRARPARENTESIS {s+= ")";} | id =ID {s += id.getText();};
 
    